from django_redis import get_redis_connection
from rest_framework import serializers

from goods.models import SKU
from .models import User,Address
from django.core.mail import send_mail
from django.conf import settings
from celery_tasks.email.tasks import send_verify_url


# 注冊序列化器
class RegisterUserSerializer(serializers.ModelSerializer):
    # write_only 只寫,只校驗,不入庫,也不需要返回前端數據
    password2 = serializers.CharField(min_length=8,max_length=20,label="確認密碼",write_only=True)
    sms_code = serializers.CharField(max_length=5,min_length=5,label="短信驗證碼",write_only=True)
    allow = serializers.CharField(label="協議",write_only=True)
    token = serializers.CharField(label="jwt口令",read_only=True)

    class Meta:
        model = User
        fields = ("id","username","password","password2","sms_code","allow","mobile","token")

        read_only_fields = ("id",)

        extra_kwargs = {
            "password":{
                "min_length":8,
                "max_length":20,
                "write_only":True
            }
        }

    # 單字段校驗
    def validate_allow(self, value):
        if value != 'true':
            raise serializers.ValidationError("必須同意協議")

        return value

    # 校驗多字段,密碼,短信
    def validate(self, attrs):
        # 取出手機號和短信驗證碼
        mobile = attrs["mobile"]
        sms_code = attrs["sms_code"]

        # 校驗密碼
        if attrs["password"] != attrs["password2"]:
            raise serializers.ValidationError("密碼不一致")

        # 校驗手機驗證碼
        redis_conn = get_redis_connection("code")
        redis_sms_code = redis_conn.get("sms_code_%s"%mobile)

        # 判斷是否過期
        if not redis_sms_code:
            raise serializers.ValidationError("驗證碼過期")

        # 校驗正確性
        if sms_code != redis_sms_code.decode():
            raise serializers.ValidationError("驗證碼錯誤")

        # 返回
        return attrs

    # 由於User中沒有password2,sms_code,allow,所以需要去除
    def create(self, validated_data):
        # 去除不需要的字段
        del validated_data["password2"]
        del validated_data["sms_code"]
        del validated_data["allow"]

        # 創建對象
        user = super(RegisterUserSerializer,self).create(validated_data)

        # 密碼加密
        user.set_password(validated_data["password"])
        user.save()

        # 设置JWT
        from rest_framework_jwt.settings import api_settings
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token

        # 返回
        return user


# 用戶中心序列化器
class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ("id","username","mobile","email","email_active")


# 保存郵箱及郵件發送序列化器
class EmailSendSerializer(serializers.Serializer):
    email = serializers.EmailField(label="郵箱")

    def update(self, instance, validated_data):
        # 將郵箱設置到用戶對象
        email = validated_data['email']
        instance.email = email

        instance.save()

        # 發送郵件
        verify_url = instance.generate_verify_url()
        send_verify_url.delay(verify_url,email)
        # send_mail(subject="請你點擊驗證,來自美多國際商城",
        #           message=verify_url,
        #           from_email=settings.EMAIL_FROM,
        #           recipient_list=[email])

        # 返回
        return validated_data


# 用戶地址獲取序列化器
class AddressSerializer(serializers.ModelSerializer):
    province = serializers.StringRelatedField(read_only=True)
    city = serializers.StringRelatedField(read_only=True)
    district = serializers.StringRelatedField(read_only=True)
    province_id = serializers.IntegerField(label="省id")
    city_id = serializers.IntegerField(label="市id")
    district_id = serializers.IntegerField(label="区id")

    class Meta:
        model = Address
        exclude = ("user","is_deleted","create_time","update_time")

    # 重寫序列化器的create方法,
    def create(self, validated_data):
        validated_data["user"] = self.context["request"].user

        return super(AddressSerializer,self).create(validated_data)


# 用戶地址標題序列化器
class AddressTitleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Address
        fields = ("title",)


# 用戶瀏覽商品記錄序列化器
class UserBrowerHistorySerializer(serializers.Serializer):
    sku_id = serializers.IntegerField(min_value=1,label="商品編號")

    # 單字段校驗
    def validate_sku_id(self, value):
        # 通過sku_id獲取sku對象
        try:
            sku = SKU.objects.get(id=value)
        except Exception as e:
            raise serializers.ValidationError("商品不存在")

        return value

    # 重寫create方法,需要保存記錄到redis
    def create(self, validated_data):
        # 獲取sku_id
        sku_id = validated_data.get("sku_id")
        user = self.context["request"].user

        # 獲取redis對象
        redis_conn = get_redis_connection("history")

        # 去重
        redis_conn.lrem("history_%s"%user.id,0,sku_id)

        # 存儲
        redis_conn.lpush("history_%s"%user.id,sku_id)

        # 截取5條
        redis_conn.ltrim("history_%s"%user.id,0,4)

        # 返回
        return validated_data
